package com.yl.nettylearning.netty.day01;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.util.CharsetUtil;


/**
 * @author yangl
 * 自定义一个handler，需要继承netty绑定好的某个handlerAdapter
 * 这时我们自定义的handler，才能称为一个handler
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * 读取数据实例
     * 1、ChannelHandlerContext ctx：上下文对象，含有管道pipeline，通道channel，地址
     * 2、Object msg：客户端发送的数据，默认Object
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{
        System.out.println("server ctx = " + ctx);
        System.out.println("服务器读取的线程是：" + Thread.currentThread().getName());
        System.out.println("debug 查看 channel 和 pipeline的关系");
        //channel和pipeline相互包含，ctx包含channel和pipeline
        Channel channel = ctx.channel();
        ChannelPipeline pipeline = ctx.pipeline();  //本质是一个双向链表，出入栈

        //将msg转成bytebuffer
        ByteBuf buffer = (ByteBuf) msg;
        System.out.println("客户端发送的消息：" + buffer.toString(CharsetUtil.UTF_8));
        System.out.println("客户端的地址是：" + ctx.channel().remoteAddress());
    }

    /**
     * 数据读取完毕
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

        //writeAndFlush是write和flush
        //将数据写入到缓存，并刷新
        //对发送的数据编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello，客户端， ^_^", CharsetUtil.UTF_8));
    }

    /**
     * 处理异常，发生异常，关闭通道
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
